package tech.aistar.day12;

import java.io.*;

/**
 * 本类用来演示: 字节流
 *
 * @author: success
 * @date: 2022/8/3 9:47 上午
 */
public class InputStreamDemo {
    public static void main(String[] args) {
        buffCopy("src/tech/aistar/day12/xx.jpg","src/tech/aistar/day12/xx_copy.jpg");
        //buffCopy("src/tech/aistar/day12/FileDemo.java","src/tech/aistar/day12/FileDemo_copy.java");
    }

    //最精简的版本 - 文件的拷贝
    //单个字节单个字节进行读写 - 性能低下的
    //原因:java程序和磁盘IO的交互比较频繁
    public static void test01(String src,String target){
        //1. 确定流
        InputStream in = null;
        OutputStream out = null;

        //2. 初始化流 - 确定源头和目标
        try {
            in = new FileInputStream(src);
            out = new FileOutputStream(target);//可以自动构建target文件

            //定义一个变量 - 读取到的字节
            int len = -1;

            //循环读取
            while(true){
                len = in.read(); //单个字节单个字节读取

                //如果没有读取到,len会返回-1
                if(len==-1)
                    break;

                //System.out.print((char)len);

                //单个字节单个字节写出去
                out.write(len);
            }
            System.out.println("文件拷贝成功");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //因为流也是一个昂贵的资源 - 消耗系统资源 - 占内存 - 释放
            if(null!=in){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(null!=out){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //版本二
    //1. 自定义缓冲数组
    //2. 语法糖写法 - 释放资源的动作交给JVM
    public static void copy(String src,String target){
        //try(资源1;资源2){...} - 资源的释放不需要我们自己去释放了.
        try(InputStream in = new FileInputStream(src);
            OutputStream out = new FileOutputStream(target)){

            //自定义一个字节数组 - 自定义缓冲区
            byte[] buf = new byte[3*1024];//3MB

            int len = -1;//保存每次读取到的字节数

            //循环读取
            while(true){
                //java程序从文件中一次性读取 3*1024个数据 放入到buf中.
                len = in.read(buf);

                if(len==-1)
                    break;
                //就是想要从buf中取数据写出去
                out.write(buf,0,len);
            }
            System.out.println("拷贝成功!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //最终版本 - 包装流
    public static void buffCopy(String src,String target){
        try(BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target))){

            int len = -1;

            //自定义数组 - 内置的8KB的数组有什么区别?
            byte[] buf = new byte[3*1024];

            while(true){
                len = in.read(buf);

                if(len==-1)
                    break;
                out.write(buf,0,len);
            }
            System.out.println("buff拷贝成功!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
